import { Commit, createStore } from "vuex";
import axios, { AxiosRequestConfig } from "axios";
//封装get请求 Commit就是commit的类型
const getAndCommit = async (
  url: string,
  mutationName: string,

  commit: Commit
) => {
  // commit("setLoading", true); //开始
  const { data } = await axios.get(url);
  commit(mutationName, data);
  // commit("setLoading", false); //结束
};
const postAndCommit = async (
  url: string,
  mutationName: string,
  commit: Commit,
  payload: any
) => {
  const { data } = await axios.post(url, payload);
  commit(mutationName, data);
};
const asyncAndCommit = async (
  url: string,
  mutationName: string,
  commit: Commit,
  config: AxiosRequestConfig = { method: "get" }
) => {
  const { data } = await axios(url, config);
  commit(mutationName, data);
  return data;
};

export interface IamgeProps {
  _id?: string;
  url?: string;
  createAt?: string;
}
export interface UserProps {
  //当前是否登录
  isLogin: boolean;
  nickName?: string;
  _id?: string;
  column?: string;
  avatar?: IamgeProps;
  description?: string;
}

export interface ColumnProps {
  _id: string;
  title: string;
  avatar?: IamgeProps;
  description: string;
}

export interface PostProps {
  _id?: string;
  title: string;
  excerpt?: string;
  content?: string; //内容
  image?: IamgeProps | string; //图片
  createdAt?: string; //创建时间
  column: string; //文章id，你点开的文章要和文章id做匹配
  author?: string | UserProps;
}
// 声明错误
export interface GolbalErrorProps {
  status: boolean;
  message?: string;
}
export interface ResponseType<P = []> {
  code: number;
  status: string;
  data: P;
}

//如果你想在其他页面使用的话导出就可以了
export interface GolbalDataProps {
  columns: ColumnProps[];
  posts: PostProps[];
  user: UserProps;
  loading: boolean;
  token: string;
  error: GolbalErrorProps;
}

const store = createStore<GolbalDataProps>({
  state: {
    columns: [],
    posts: [],
    user: {
      isLogin: false,
    },
    loading: false,
    token: localStorage.getItem("token") || "",
    error: { status: false },
  },
  getters: {
    //定义完毕，在应用中使用这个getters
    //Getters
    // biggerColumnLen(state) {
    //   return state.columns.filter((c) => c._id > 2).length;
    // },
    getColumnById: (state) => (id: string) => {
      return state.columns.find((c) => c._id === id);
    },
    getPostById: (state) => (id: string) => {
      return state.posts.filter((post) => post.column === id);
    },
    getCurrentPost: (state) => (id: number) => {
      return state.posts[id];
    },
  },
  mutations: {
    //登录
    login(state, rawData) {
      const { token } = rawData.data;
      state.token = token;
      localStorage.setItem("token", token);
      axios.defaults.headers.common.Authorization = `Bearer ${token}`;
      // state.user = { ...state.user, isLogin: true, nickName: "小小" };
    },
    loginOut(state) {
      state.token = "";
      localStorage.removeItem("token");
      delete axios.defaults.headers.common.Authorization;
    },
    fetchCurrentUser(state, rawData) {
      state.user = { isLogin: true, ...rawData.data };
    },
    //新建文章
    createPost(state, newPost) {
      state.posts.push(newPost);
    },
    //专栏列表
    fetchColumns(state, rwaData) {
      state.columns = rwaData.data.list;
    },
    //  专栏详情
    fetchColumn(state, rwaData) {
      state.columns = [rwaData.data];
    },
    //文章列表
    fetchPosts(state, rwaData) {
      state.posts = rwaData.data.list;
    },
    //文章详情
    fetchPost(state, rawData) {
      state.posts[rawData.data._id] = rawData.data;
      // console.log(rawData.data);
    },
    updatePost(state, { data }) {
      // state.posts[data._id] = data;
      state.posts = state.posts.map((post) => {
        if (post._id === data._id) {
          return data;
        } else {
          return post;
        }
      });
    },
    deletePost(state, { data }) {
      state.posts = state.posts.filter((post) => post._id !== data.id);
    },

    setLoading(state, status) {
      state.loading = status; //true和false 的值
    },
    //消息错误提示
    setError(state, e: GolbalErrorProps) {
      state.error = e;
    },
  },
  //actions提交的mutations，而不是直接改变状态，类似于mutations
  actions: {
    //专栏列表
    fetchColumns(context) {
      // axios.get("/columns").then((resp) => {
      //   context.commit("fetchColumns", resp.data);
      // });
      // const { data } = await axios.get("/columns");
      // context.commit("fetchColumns", data);
      getAndCommit("/columns", "fetchColumns", context.commit);
    },
    //文章详情
    fetchColumn({ commit }, cid) {
      // axios.get(`/columns/${cid}`).then((resp) => {
      //   commit("fetchColumn", resp.data);
      // });
      // const { data } = await axios.get(`/columns/${cid}`);
      // commit("fetchColumn", data);

      getAndCommit(`/columns/${cid}`, "fetchColumn", commit);
    },
    //文章列表
    fetchPosts({ commit }, cid) {
      // axios.get(`/columns/${cid}/posts`).then((resp) => {
      //   commit("fetchPosts", resp.data);
      // });
      // const { data } = await axios.get(`/columns/${cid}/posts`);
      // commit("fetchPosts", data);
      getAndCommit(`/columns/${cid}/posts`, "fetchPosts", commit);
    },
    fetchPost({ state, commit }, id) {
      const currentPost = state.posts[id];
      if (!currentPost || !currentPost.content) {
        return getAndCommit(`/posts/${id}`, "fetchPost", commit);
      } else {
        return Promise.resolve({ data: currentPost });
      }
    },
    updatePost({ commit }, { id, payload }) {
      return asyncAndCommit(`/posts/${id}`, "updatePost", commit, {
        method: "patch",
        data: payload,
      });
    },
    deletePost({ commit }, id) {
      return asyncAndCommit(`/posts/${id}`, "deletePost", commit, {
        method: "delete",
      });
    },
    login({ commit }, payload) {
      return postAndCommit("/user/login", "login", commit, payload);
    },
    fetchCurrentUser({ commit }) {
      getAndCommit("/user/current", "fetchCurrentUser", commit);
    },
    loginAndFecth({ dispatch }, loginData) {
      return dispatch("login", loginData).then(() => {
        //获取到token在获取用户信息
        return dispatch("fetchCurrentUser");
      });
    },
    createPost({ commit }, payload) {
      return postAndCommit("/posts", "createPost", commit, payload);
    },
  },
  modules: {},
});

export default store;
